package org.wattdepot.cli.command;

import java.util.List;
import javax.xml.datatype.XMLGregorianCalendar;
import org.wattdepot.cli.processor.CommandLineInterface;
import org.wattdepot.client.ResourceNotFoundException;
import org.wattdepot.resource.sensordata.jaxb.SensorData;
import org.wattdepot.resource.property.jaxb.Property;
import org.wattdepot.resource.source.jaxb.Source;

/**
 * ListSensorStamp class returns the output wattage in Watts of a specific source entered by the
 * user on a given timestamp. This class extends CommandLineInterface to have access to the
 * WattDepotClient and implements WattDepotCliCommand interface to ensure this class does a specific
 * command.
 * 
 * @author Edward Meyer, Bao Huy Ung
 * 
 */
public class ListSensorStamp extends CommandLineInterface implements WattDepotCliCommand {

  /**
   * Creates a ListSensorStamp object to return the output wattage of a source on a given timestamp.
   */
  public ListSensorStamp() {
    // Empty constructor.
  }

  /**
   * Returns the output wattage in Watts of a specific source entered by the user on a given
   * timestamp.
   * 
   * @param args Is a list of all the arguments entered by the user.
   * @return A string containing sensor data about a source entered by user, or an error message.
   */
  public String doCommand(List<String> args) {
    // If there are too few or too many arguments, return an error message.
    if (args.size() != 4) {
      return "Error: Incorrect number of arguments were entered. Expected 4, instead "
          + args.size() + " were entered.";
    }
    // Check is proper keywords were used to enter the command.
    if (!args.get(2).equalsIgnoreCase("timestamp")) {
      return "Error: Keyword \"timestamp\" was mistyped as \"" + args.get(2) + "\".";
    }

    String inputSourceName = args.get(1);
    String inputStamp = args.get(3);
    XMLGregorianCalendar timeStamp = null;
    SensorData sourceData = null;
    Source printSource = null;

    // String variable that will hold all the information.
    StringBuffer output = new StringBuffer(200);

    // Check if a valid source was entered.
    printSource = isValidSource(inputSourceName);
    if (printSource == null) {
      return "\"" + inputSourceName + "\" is not a valid source.";
    }

    // Attempt to parse the entered timestamp to see if it's a valid timestamp.
    timeStamp = isValidTimestamp(inputStamp);
    if (timeStamp == null) {
      return "Timestamp Error: \"" + inputStamp + "\" cannot be parsed into a timestamp.";
    }

    // Check to see if the timestamp entered contains sensor data.
    try {
      sourceData = client.getSensorData(inputSourceName, timeStamp);
      output.append("Tool: ");
      output.append(sourceData.getTool());
      output.append(cr);
      output.append("Source: ");
      output.append(sourceData.getSource().substring(
          sourceData.getSource().indexOf("/sources/") + 9));
      output.append(cr);

      output.append("Properties: ");
      // Check if the given source has properties.
      if (printSource.isSetProperties()) {
        // Print every property of the given source.
        for (Property property : sourceData.getProperties().getProperty()) {
          output.append('(');
          output.append(property.getKey());
          output.append(" : ");
          // Convert to megawatts.
          output.append((Double.parseDouble(property.getValue()) / 1000000.0));
          output.append(" MW)");
        }
        output.append(cr);
      }
      else {
        // Source had no properties.
        output.append("None");
      }

    }
    catch (ResourceNotFoundException r) {
      return "No data found for \"" + inputSourceName + "\" on timestamp: " + "\""
          + timeStamp.toString() + "\"";
    }
    // If an unknown error occurs.
    catch (Exception e) {
      return "An error occurred when retrieving sensor data from the server. \n" + e;
    }
    return output.toString();
  }

}
